﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Threading;
using Microsoft.Expression.Interactivity.Core;
using System.Windows.Input;
using System.Windows;

namespace Twittit.WPF
{
    public class MainViewModel : INotifyPropertyChanged
    {

       public event PropertyChangedEventHandler PropertyChanged;
       ServiceReferenceUser.ServiceUserClient client;

       private void Raise(string propName){
            if(PropertyChanged != null){
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
       }

       public MainViewModel(){}
 
       public void init(Twittit.DataAccess.User u){
           this.User = u;
           //  DispatcherTimer setup
           var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
           dispatcherTimer.Tick += new EventHandler(refreshTwittits);
           dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
           dispatcherTimer.Start();

           var dispatcherTimerFollow = new System.Windows.Threading.DispatcherTimer();
           dispatcherTimerFollow.Tick += new EventHandler(refreshFollow);
           dispatcherTimerFollow.Interval = new TimeSpan(0, 5, 0);
           dispatcherTimerFollow.Start();

           this.client = new ServiceReferenceUser.ServiceUserClient();
           NbTwittits = client.CountUserPosts(User.id);
           List<Twittit.DataAccess.Twit> listTwitts = this.client.GetTwitts(User.id);
           List<Twittit.DataAccess.Twit> listTwittsUser = this.client.GetUserTwitts(User.id);
           List<Twittit.DataAccess.User> listGravatars = this.client.SuggestUsers(User.id);
 
           //List<Twittit.DataAccess.Twit> listTwitts = Twittit.Business.UserService.getInstance().getTwitts(User.id);
           //List<Twittit.DataAccess.Twit> listTwittsUser = Twittit.Business.UserService.getInstance().getUserTwitts(User.id);
           //List<Twittit.DataAccess.User> listGravatars = Twittit.Business.UserService.getInstance().suggestUsers(User.id);

           Twitts = new ObservableCollection<DataAccess.Twit>(listTwitts);
           TwittsUser = new ObservableCollection<DataAccess.Twit>(listTwittsUser);
           Gravatars = new ObservableCollection<DataAccess.User>(listGravatars);
           //Twitts.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(refreshNbTwittits);

           
           //NbTwittits = Business.UserService.getInstance().countUserPosts(User.id);

           Subscribed = Twittit.Business.UserService.getInstance().countSubscribed(User.id);
           Subscribers = Twittit.Business.UserService.getInstance().countSubscribers(User.id);
           NbDemandes = Twittit.Business.UserService.getInstance().countPendingRequests(User.id);
       }

       public void refreshTwittits(object sender, EventArgs e)
       {
           List<Twittit.DataAccess.Twit> listTwitts = Twittit.Business.UserService.getInstance().getTwitts(User.id);
           Twitts = new ObservableCollection<DataAccess.Twit>(listTwitts);
           List<Twittit.DataAccess.Twit> listTwittsUser = Twittit.Business.UserService.getInstance().getUserTwitts(User.id);
           TwittsUser = new ObservableCollection<DataAccess.Twit>(listTwittsUser);

           NbTwittits = TwittsUser.Count;
       }

       private void refreshFollow(object sender, EventArgs e)
       {
           Subscribed = Twittit.Business.UserService.getInstance().countSubscribed(User.id);
           Subscribers = Twittit.Business.UserService.getInstance().countSubscribers(User.id);
           NbDemandes = Twittit.Business.UserService.getInstance().countPendingRequests(User.id);
       }

 
        private String _textTwitt;
        public String TextTwitt
        {
            get { return _textTwitt; }
            set { _textTwitt = value; Raise("TextTwitt"); }
        }

        private int _nbTwittits;
        public int NbTwittits
        {
            get { return _nbTwittits; }
            set { _nbTwittits = value; Raise("nbTwittits"); }
        }

        private int _nbDemandes;
        public int NbDemandes
        {
            get { return _nbDemandes; }
            set { _nbDemandes = value; Raise("nbDemandes"); }
        }

        private int _userOtherNbTwittits;
        public int UserOtherNbTwittits
        {
            get { return _userOtherNbTwittits; }
            set { _userOtherNbTwittits = value; Raise("userOtherNbTwittits"); }
        }

        private int _userOtherSubscribed;
        public int UserOtherSubscribed
        {
            get { return _userOtherSubscribed; }
            set { _userOtherSubscribed = value; Raise("userOtherSubscribed"); }
        }

        private int _subscribed;
        public int Subscribed
        {
            get { return _subscribed; }
            set { _subscribed = value; Raise("subscribed"); }
        }

        ObservableCollection<DataAccess.Twit> _twittsUser;
        public ObservableCollection<DataAccess.Twit> TwittsUser
        {
            get { return _twittsUser; }
            set { _twittsUser = value; Raise("twittsUser"); }
        }

        ObservableCollection<DataAccess.Twit> _userOtherTwittsUser;
        public ObservableCollection<DataAccess.Twit> UserOtherTwittsUser
        {
            get { return _userOtherTwittsUser; }
            set { _userOtherTwittsUser = value; Raise("userOtherTwittsUser"); }
        }


        private Boolean _userOtherIsHide;
        public Boolean UserOtherIsHide
        {
            get { return _userOtherIsHide; }
            set { _userOtherIsHide = value; Raise("userOtherIsHide"); }
        }

        private int _subscribers;
        public int Subscribers
        {
            get { return _subscribers; }
            set { _subscribers = value; Raise("subscribers"); }
        }

        private int _userOtherSubscribers;
        public int UserOtherSubscribers
        {
            get { return _userOtherSubscribers; }
            set { _userOtherSubscribers = value; Raise("userOthersubscribers"); }
        }

        private Twittit.DataAccess.User _user;
        public Twittit.DataAccess.User User
        {
            get { return _user; }
            set { _user = value;
                Raise("user"); }
        }

        private Twittit.DataAccess.User _userOther;
        public Twittit.DataAccess.User UserOther
        {
            get { return _userOther; }
            set
            {
                _userOther = value;
                Raise("userOther");
            }
        }

        private ObservableCollection<Twittit.DataAccess.Twit> _twitts;
        public ObservableCollection<Twittit.DataAccess.Twit> Twitts{
            get{ return _twitts; }
            set{ _twitts = value; Raise("Twitts"); }
        }


        private ObservableCollection<Twittit.DataAccess.User> _gravatars;
        public ObservableCollection<Twittit.DataAccess.User> Gravatars
        {
            get { return _gravatars; }
            set { _gravatars = value; Raise("Gravatars"); }
        }

        private ICommand _btnModifyUser;
        public ICommand BtnModifyUser
        {
            get
            {
                if (_btnModifyUser == null)
                {
                    _btnModifyUser = new RelayCommand(
                        param => this.DoSaveUser(),
                        param => this.DoCanEditUser()
                    );
                }
                return _btnModifyUser;
            }
        }

        private bool DoCanEditUser()
        {
            return true;
        }

        private void DoSaveUser()
        {
            Twittit.DataAccess.User u = this.client.GetUser(this.User.id);
            this.User = this.client.EditUser(u, this.User.name, this.User.twittit, this.User.email, this.User.website, this.User.localisation, this.User.aboutyou, (byte)this.User.confirmSubscription, Convert.ToBoolean(this.User.connectToTwitter), this.User.id);
        }

        private ICommand _btnAccessProfil;
        public ICommand BtnAccessProfil
        {
            get
            {
                if (_btnAccessProfil == null)
                {
                    _btnAccessProfil = new RelayCommand(
                        param => this.DoAccessProfil(param as Twittit.DataAccess.User),
                        param => this.DoCanAccessProfil()
                    );
                }
                return _btnAccessProfil;
            }
        }

        private bool DoCanAccessProfil()
        {
            return true;
        }

        private void DoAccessProfil(Twittit.DataAccess.User u)
        {

            List<Twittit.DataAccess.Twit> listTwittsUser = client.GetUserTwitts(u.id);
           // List<Twittit.DataAccess.Twit> listTwittsUser = Twittit.Business.UserService.getInstance().getUserTwitts(u.id);
            this.UserOtherTwittsUser = new ObservableCollection<DataAccess.Twit>(listTwittsUser);
            this.UserOther = u;
            UserOtherNbTwittits = Twittit.Business.UserService.getInstance().countUserPosts(u.id);

            UserOtherSubscribed = Twittit.Business.UserService.getInstance().countSubscribed(u.id);
            UserOtherSubscribers = Twittit.Business.UserService.getInstance().countSubscribers(u.id);
        }

        private ICommand _saveTwitt;
        public ICommand SaveTwitt
        {
            get
            {
                if (_saveTwitt == null)
                {
                    _saveTwitt = new RelayCommand(
                        param => this.DoSaveTwitt(),
                        param => this.DoCanTwitt()
                    );
                }
                return _saveTwitt;
            }
        }

        private bool DoCanTwitt()
        {
            return true;
        }

        private void DoSaveTwitt()
        {
            if (this.TextTwitt != null && this.TextTwitt.Trim() != "")
            {
                Twittit.DataAccess.Twit last = Twittit.Business.UserService.getInstance().addTwitt(User.id, this.TextTwitt);
                this.TextTwitt = "";
                this.Twitts.Insert(0,last);
                NbTwittits = Twitts.Count;
			}
  
        }

        private ICommand _btnLogout;
        public ICommand BtnLogout
        {
            get
            {
                if (_btnLogout == null)
                {
                    _btnLogout = new RelayCommand(
                        param => this.DoLogout(),
                        param => this.DoCanLogout()
                    );
                }
                return _btnLogout;
            }
        }

        private bool DoCanLogout()
        {
            return true;
        }

        private void DoLogout()
        {
            foreach(System.Windows.Window w in App.Current.Windows)
            {
                if (w.Name == "Login")
                    w.Show();
                else if (w.Name == "Main")
                    w.Hide();
            }
            
        }
        
        private ICommand _deleteTwitt;
        public ICommand DeleteTwitt
        {
            get
            {
                if (_deleteTwitt == null)
                {
                    _deleteTwitt = new RelayCommand(
                        param => this.DoDeleteTwitt(param as Twittit.DataAccess.Twit),
                        param => this.DoCanDeleteTwitt(param as Twittit.DataAccess.Twit)
                    );
                }
                return _deleteTwitt;
            }
        }

        private bool DoCanDeleteTwitt(Twittit.DataAccess.Twit tw)
        {
            bool b = false;
            if (User.id == tw.user_id)
                b = true;
            return b;
        }

        private void DoDeleteTwitt(Twittit.DataAccess.Twit tw)
        {
            if (MessageBox.Show("Voulez vous supprimer ce twittit ?", "Supprimer un message", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                this.client.RemoveTwitt(tw.id, tw.user_id);
                // Refresh de la liste
                refreshTwittits(null, null);
            }
        } 
        
        private ICommand _forwardTwitt;
        public ICommand ForwardTwitt
        {
            get
            {
                if (_forwardTwitt == null)
                {
                    _forwardTwitt = new RelayCommand(
                        param => this.DoForwardTwitt(param as Twittit.DataAccess.Twit),
                        param => this.DoCanForwardTwitt()
                    );
                }
                return _forwardTwitt;
            }
        }

        private bool DoCanForwardTwitt()
        {
            return true;
        }

        private void DoForwardTwitt(Twittit.DataAccess.Twit tw)
        {
            this.TextTwitt = "RT "+tw.User.twittit+" "+tw.text;
        }
    }
}